package topopt;

import fem2.AbstractStructuralStaticDemo;
import fem2.Constraint;
import fem2.Force;
import fem2.MaterialModel;
import fem2.Mesh;
import fem2.MeshGenerator;
import fem2.MeshUtilities;
import fem2.Model;
import fem2.Node;
import fem2.enu.State;
import fem2.material.ElasticMaterialModel;
import fem2.material.StVenantKirchhoffMM;
import fem2.material.TopOptFilter;
import fem2.material.TopOptMaterialModel;
import fem2.material.TopOptSensitivityFilter;
import fem2.pre_and_post.GidMeshGenerator;

public class Beam3dTopOptDemo extends AbstractTopOptDemo {

	public Beam3dTopOptDemo() {
		projectName = "beam3d-topopt.gid";
		meshFileName = "mesh2.msh";
	}

	@Override
	public Mesh createMesh() {
		String fn = projectDir + '/' + projectName + '/' + meshFileName;
		MeshGenerator mg = new GidMeshGenerator(fn);
		return mg.getMesh(3);
	}

	@Override
	public TopOptFilter createFilter(Model m) {
		double rmin = 15;
		TopOptFilter filter = new TopOptSensitivityFilter(m, rmin);
		return filter;
	}

	@Override
	public MaterialModel createMaterial(Model m) {
		double E = 1.0;
		double nu = 0.3;
		double t = 1.0;
		ElasticMaterialModel mm = new StVenantKirchhoffMM(E, nu, t, 0.0, State.THREE_DIMENSIONAL);
		double Emin = 1e-9;
		double volfrac = 0.5;
		double penal = 3;

		TopOptFilter filter = createFilter(m);

		MaterialModel topmm = new TopOptMaterialModel(mm, E, Emin, penal, volfrac, filter);

		return topmm;
	}

	@Override
	public Model createConditions(Model m) {
		Constraint c1 = new Constraint(false, false, false);
		Mesh mesh = m.getMesh();
		mesh.setConstraint(c1, MeshUtilities.seekNodesOnSurface(mesh, 1, 0, 0, 0));

		Node n = MeshUtilities.seekNode(mesh, 60, 10, 10);
		double F = -1;
		Force f = new Force(n, 0, F, 0);
		m.addLoad(f);
		return m;
	}

	public static void main(String[] args) {
		AbstractStructuralStaticDemo demo = new Beam3dTopOptDemo();

		demo.run();
	}
}
